home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / mg2a_src.zip / SYS / AMIGA / FILEIO.C < prev    next >
C/C++ Source or Header  |  1988-08-23  |  13KB  |  536 lines

  1. /*
  2.  * Name:    MG 2a401
  3.  *        Commodore Amiga file I/O.
  4.  * Last edit:    05-May-88 swalton@solar.stanford.edu
  5.  * Next-to-Last edit:    16-Dec-87 mic@emx.utexas.edu
  6.  * Created:    23-Jul-86 mic@emx.utexas.edu
  7.  *
  8.  * Read and write ASCII files. All of the low level file I/O
  9.  * knowledge is here.  Uses AmigaDOS standard I/O and does its
  10.  * own dynamic buffering; this seems to save about 2K worth
  11.  * of space in the executable image.
  12.  */
  13.  
  14. #ifdef        LATTICE
  15. #include    <string.h>
  16. #include    <exec/types.h>
  17. #endif
  18. #include    <exec/memory.h>
  19. #include    <libraries/dos.h>
  20. #include    <libraries/dosextens.h>
  21. #ifdef        USE_ARP
  22. #include    "libraries/arpbase.h"
  23. #else
  24. #define FCHARS    32L
  25. #endif
  26.  
  27. #undef    TRUE
  28. #undef    FALSE
  29. #include    "def.h"
  30.  
  31. #define    NIOBUF            4096
  32.  
  33. extern ULONG            Rename(), UnLock(), Close(), FreeMem();
  34. extern LONG            Write(), Read();
  35. extern UBYTE            *AllocMem();
  36. extern struct FileLock        *Lock();
  37. extern struct FileHandle    *Open();
  38.  
  39. static struct FileHandle    *ffh = 0;
  40. static UBYTE            *iobuf;
  41. static int            ibufo, niobuf;
  42. static LONG            iostat, access_mode;
  43. #ifdef    MANX
  44. extern char            *strncpy(), *strncat(), *index(), *rindex();
  45. #endif
  46. #ifdef    LATTICE
  47. extern char            *malloc() ;
  48. #define    index    strchr
  49. #define rindex    strrchr
  50. #endif
  51.  
  52. #define    getch()        (ibufo == niobuf) ? FillBuf() : iobuf[ibufo++]
  53. #define putch(c)    {if (niobuf == NIOBUF) FlushBuf(); iobuf[niobuf++] = c;}
  54.  
  55. /*
  56.  * Open the Emacs internal file for reading.
  57.  */
  58. ffropen(fn)
  59. char    *fn;
  60. {
  61.     if ((iobuf = AllocMem((ULONG) NIOBUF, 0L)) == NULL)
  62.         return (FIOERR);
  63.  
  64.     if ((ffh = Open(fn, access_mode = MODE_OLDFILE)) == 0L) {
  65.         FreeMem(iobuf, (ULONG) NIOBUF);
  66.         return (FIOFNF);
  67.     }
  68.     ibufo = niobuf = 0;
  69.     return (FIOSUC);
  70. }
  71.  
  72. /*
  73.  * Open a file for writing.  Return TRUE if all
  74.  * is well, and FALSE on error (cannot create).
  75.  */
  76.  
  77. ffwopen(fn)
  78. char    *fn;
  79. {
  80.     if ((iobuf = AllocMem((ULONG) NIOBUF, 0L)) == NULL)
  81.         return (FIOERR);
  82.     if ((ffh = Open(fn, access_mode = MODE_NEWFILE)) == 0L) {
  83.         ewprintf("Cannot open file for writing");
  84.         FreeMem(iobuf, (ULONG) NIOBUF);
  85.         return (FIOERR);
  86.     }
  87.     niobuf = 0;
  88.     iostat = NIOBUF;    /* pretend we wrote out a full buffer last time */
  89.     return (FIOSUC);
  90. }
  91.  
  92. /*
  93.  * Close a file, flushing the output buffer.  Should look at
  94.  * the status.
  95.  */
  96. ffclose()
  97. {
  98.     if (access_mode == MODE_NEWFILE)
  99.         FlushBuf();
  100.     if (ffh)
  101.         (void) Close(ffh);
  102.     if (iobuf)
  103.         FreeMem(iobuf, (ULONG) NIOBUF);
  104.     return (FIOSUC);
  105. }
  106.  
  107. /*
  108.  * Write a buffer to the already opened file. bp points to the
  109.  * buffer. Return the status. Check only at the newline and
  110.  * end of buffer.
  111.  */
  112. ffputbuf(bp)
  113. BUFFER *bp;
  114. {
  115.     register char *cp;
  116.     register char *cpend;
  117.     register LINE *lp;
  118.     register LINE *lpend;
  119.  
  120.     lpend = bp->b_linep;
  121.     lp = lforw(lpend);
  122.     do {
  123.     cp = <ext(lp)[0];        /* begining of line    */
  124.     cpend = &cp[llength(lp)];    /* end of line        */
  125.     while(cp != cpend)
  126.         putch(*(cp++));        /* putch only evalutes its arg once */
  127.     lp = lforw(lp);
  128.     if(lp == lpend) break;        /* no implied newline on last line */
  129.     putch('\n');
  130.     } while(iostat > 0L);
  131.  
  132.     if(iostat == -1L) {
  133.     ewprintf("Write I/O error");
  134.     return FIOERR;
  135.     }
  136.     return FIOSUC;
  137. }
  138.  
  139. /*
  140.  * Read a line from a file, and store the bytes
  141.  * in the supplied buffer. Stop on end of file or end of
  142.  * line.  When FIOEOF is returned, there is a valid line
  143.  * of data without the normally implied \n.
  144.  */
  145. ffgetline(buf, nbuf, nbytes)
  146. register char    *buf;
  147. register int    nbuf;
  148. register int    *nbytes;
  149. {
  150.     register int    c;
  151.     register int    i;
  152.  
  153.     i = 0;
  154.     while((c = getch())!=EOF && c!='\n') {
  155.         buf[i++] = c;
  156.         if (i >= nbuf) return FIOLONG;
  157.     }
  158.     if (c == EOF  && (iostat == -1L)) {
  159.         ewprintf("File read error");
  160.         return FIOERR;
  161.     }
  162.     *nbytes = i;
  163.     return c==EOF ? FIOEOF : FIOSUC;
  164. }
  165.  
  166. #ifndef    NO_BACKUP
  167. /*
  168.  * Rename the current file into a backup copy,
  169.  * possibly after deleting the original file.
  170.  */
  171. fbackupfile(fname)
  172. char    *fname;
  173. {
  174.     struct FileLock *twiddle, *lock;
  175.     char buffer[NFILEN];
  176.  
  177.     (void) strncpy(buffer,fname,NFILEN - 1);
  178.     (void) strcat(buffer,"~");
  179.  
  180.     lock = Lock(fname,(ULONG)EXCLUSIVE_LOCK);/* does file exist?    */
  181.     if (!lock)
  182.         return (FALSE);            /* nope, return error    */
  183.  
  184.     twiddle = Lock(buffer,(ULONG)EXCLUSIVE_LOCK);
  185.     if (twiddle) {                /* delete old backup    */
  186.         UnLock(twiddle);        /* let it go        */
  187.         if (!DeleteFile(buffer)) {
  188.             UnLock(lock);
  189.             return (FALSE);
  190.         }
  191.         twiddle = NULL;
  192.     }
  193.     /* rename file to backup name (after unlocking the file)
  194.      */
  195.     UnLock(lock);
  196.     return (int) Rename(fname,buffer);
  197. }
  198. #endif    NO_BACKUP
  199.  
  200. #ifndef    NO_STARTUP
  201. /*
  202.  * Return name of user's startup file.  On Amiga, make it
  203.  * .mg in the current directory, then s:.mg
  204.  */
  205.  
  206. static char startname[] = ".mg";
  207. static char altstartname[] = "s:.mg";
  208.  
  209. char *startupfile()
  210. {
  211.     struct FileLock *lock;
  212.  
  213.     if (lock = Lock(startname,(ULONG)SHARED_LOCK)) {
  214.         UnLock(lock);
  215.         return(startname);
  216.     }
  217.     if (lock = Lock(altstartname,(ULONG)SHARED_LOCK)) { /* alternate */
  218.         UnLock(lock);
  219.         return (altstartname);
  220.     }
  221.     return (NULL);
  222. }
  223. #endif    NO_STARTUP
  224.  
  225. /*
  226.  * The string "fn" is a file name. Perform any required name adjustments,
  227.  * including conversion to a fully qualified path if NO_DIR isn't defined.
  228.  */
  229.  
  230. #define MAX_ELEMS      8        /* Maximum number of elements    */
  231. extern char MyDirName[];
  232.  
  233. char *adjustname(fn)
  234. register char    *fn;
  235. {
  236. #ifndef NO_DIR
  237.     static char fnb[MAX_ELEMS*FCHARS + 1];
  238.     struct FileLock *lock;
  239.     long PathName();
  240.     void TackOn();
  241.     char *dup, *p;
  242.  
  243.     if (!index(fn, ':')) {            /* no device        */
  244.         strcpy(fnb, MyDirName);
  245.         TackOn(fnb, fn);
  246.         if (!index(fn, '/'))        /* completely bare name */
  247.             return fnb;
  248.     } else
  249.         strcpy(fnb, fn);
  250.     /*
  251.      * Else fn has some path components in it.  We try to PathName
  252.      * the whole thing first, but since the file specified by fn
  253.      * may not exist, we PathName the leading part and TackOn the
  254.      * trailing part if it doesn't.
  255.      */
  256.     if (lock = Lock(fnb, SHARED_LOCK)) {
  257.         if (PathName(lock, fnb, (long) MAX_ELEMS) !=0) {
  258.             UnLock(lock);
  259.             return fnb;
  260.         }
  261.         ewprintf("adjustname: PathName() failed!");
  262.         UnLock(lock);
  263.         return fn;
  264.     }
  265.     if (!(p = rindex(fnb, '/')))
  266.         p = index(fnb, ':');
  267.     p++;
  268.     strcpy((dup = malloc(strlen(p) + 1)), p);
  269.     *p = '\0';
  270.     if (lock = Lock(fnb, SHARED_LOCK)) {
  271.         if (PathName(lock, fnb, (long) MAX_ELEMS) != 0) {
  272.             UnLock(lock);
  273.             TackOn(fnb, dup);
  274.             free(dup);
  275.             return fnb;
  276.         }
  277.         ewprintf("adjustname: PathName() failed!");
  278.         UnLock(lock);
  279.     }
  280.     free(dup);
  281. #endif
  282.     return fn;                /* if all else fails    */
  283. }
  284.  
  285. /*
  286.  * Functions to read/write into the I/O buffer
  287.  */
  288.  
  289. int FlushBuf()
  290. {
  291.     if (niobuf > 0) {
  292.         iostat = Write(ffh, iobuf, (ULONG) niobuf);
  293.         niobuf = 0;
  294.     }
  295. }
  296.  
  297. /*
  298.  * Fill up the input buffer and return the first character in it.
  299.  */
  300. int FillBuf()
  301. {
  302.     if ((iostat = Read(ffh, iobuf, (ULONG) NIOBUF)) <= 0L)
  303.         return (EOF);
  304.     ibufo = 0;
  305.     niobuf = (int) iostat;
  306.     return (int) (iobuf[ibufo++]);
  307. }
  308.  
  309. #ifndef NO_DIRED
  310.  
  311. #include "kbd.h"
  312.  
  313. copy(frname, toname)
  314. char *frname, *toname;
  315. {
  316. #ifdef    MANX
  317.     return fexecl("copy", "copy", frname, toname, (char *) 0);
  318. #endif
  319. #ifdef    LATTICE
  320.     int    error ;
  321.     if (error = forkl("copy", "copy", frname, toname, (char *) 0, (char *) 0, 2))
  322.         return error ;
  323.     return (int) wait(2) ;
  324. #endif
  325. }
  326.  
  327. BUFFER *dired_(dirname)
  328. char *dirname;
  329. {
  330.     register BUFFER *bp;
  331.     char line[256];
  332.     BUFFER *findbuffer();
  333.     char *tmpname, *mktemp();
  334.     int i;
  335.     VOID lfree();
  336.  
  337.     if((dirname = adjustname(dirname)) == NULL) {
  338.     ewprintf("Bad directory name");
  339.     return NULL;
  340.     }
  341.     if(!isdirectory(dirname)) {
  342.     ewprintf("Not a directory: %s", dirname);
  343.     return NULL;
  344.     }
  345.     if((bp = findbuffer(dirname)) == NULL) {
  346.     ewprintf("Could not create buffer");
  347.     return NULL;
  348.     }
  349.     bclear(bp);                /* clear out leftover garbage    */
  350.     (void) strcpy(line, "list >");
  351.     (void) strncat(line, tmpname = mktemp("ram:mgXXX.XXX"), sizeof(line));
  352.     (void) strncat(line, " \"", sizeof(line));
  353.     (void) strncat(line, dirname, sizeof(line));
  354.     (void) strncat(line, "\"", sizeof(line));
  355.     Execute(line, 0L, 0L);
  356.     if (f